import time
# 1.条件判断not and or  ----> !  &&  ||
a = int(input("Please input a num:"))
if a > 2 and a < 10:
    print(a)
elif a > 10 and a < 50:
    print(f"test->{a}")
elif a == 88:
    print("Whiat a lucky guy!")
else:
    print(f'finally a = {a}')
"""
执行结果
    Please input a num:77
    finally a = 77
"""

# 2. all any
l = [1 > 2,2,3,4]
print(all(l))
print(any(l))
l2 = [0 < 22, 1,2,3]
print(all(l2))
print(any(l2))
l3 = {1 > 2, 2 > 3, 3 > 4}
print(any(l3))
"""
执行结果
    False
    True
    True
    True
    False
"""

# 3.循环
count = 0
while True:
    print(f"[{count + 1}]:you are beautiful!")
    time.sleep(0.1)
    count += 1
    if(count >= 10):
        break

for i in range(10):
    print(i)
"""
执行结果
    [1]:you are beautiful!
    [2]:you are beautiful!
    [3]:you are beautiful!
    [4]:you are beautiful!
    [5]:you are beautiful!
    [6]:you are beautiful!
    [7]:you are beautiful!
    [8]:you are beautiful!
    [9]:you are beautiful!
    [10]:you are beautiful!
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
"""

# 4.错误和异常捕获
filePath = ["./test.txt","./no_such_file.txt"]
for fp in filePath:
    try:
        f = open(fp, "r",encoding='utf-8')
        print(f'open {fp} ok')
    except: #出错这里执行
        print(f'open {fp} failed')
    else:   #不出错执行这里
        content = f.read()
        print(f'content:{content}')
    finally:#不管异常不异常，都执行这里
        print("I am a test")

# print(assert(1 not 2, "ok"))
# assert:断言，表达式返回false 时，直接抛出异常终止继续执行
a = -1
assert a < 0, "出错了啊，大哥"  #Exception has occurred: AssertionError
print("0001 收到请回答！")

# raise:向上抛出错误
# try:
#     a = input("输入一个数：")
#     #判断用户输入的是否为数字
#     if(not a.isdigit()):
#         # raise ValueError("a 必须是数字") #Exception has occurred: ValueError
#         raise #Exception has occurred: RuntimeError 默认
# except ValueError as e:
#     print("引发异常：",repr(e))
#     raise
"""
执行结果
    open ./test.txt ok
    content:我是一个大帅哥！！！！
    I am a test
    open ./no_such_file.txt failed
    I am a test
    0001 收到请回答！
"""

# 5.函数
file_path = "./test.txt"
def read_file(file_path):
    """
    读取文件内容
    """
    #with 打开文件，不需要手动关闭
    with open(file_path, 'r', encoding='utf-8') as f:
        ret = f.read()
        print(ret)
    return ret

read_file(file_path)

# 5.1   *args：表示任意多个无名参数，是一个tuple(元组)
#       **kwargs：表示关键字参数，是一个字典，同时使用*args要在那**kwargs之前
def funcName(*args, **kwargs):
    print(f'args type:{type(args)}')
    print(f'kwargs type:{type(kwargs)}')
    print(f'args value:{args}')
    print(f'kwargs value:{kwargs}')

funcName("nice","to","meet","you",a=1,b="hello",c=4,d="I am fine,and you?")
"""
执行结果
    我是一个大帅哥！！！！
    args type:<class 'tuple'>
    kwargs type:<class 'dict'>
    args value:('nice', 'to', 'meet', 'you')
    kwargs value:{'a': 1, 'b': 'hello', 'c': 4, 'd': 'I am fine,and you?'}
"""
# 5.2 缺省参数
def print_info(name, title='', gender=True):
    gender_text = "帅哥"
    if not gender:
        gender_text = "美女"
    print(f'{title} {name} 是 {gender_text}')

print_info('二两')
print_info('二两', False)
print_info('二两' , "工程师")
print_info('二两' , gender = False)#不显示传的话，false会被赋值给title
"""
执行结果
    二两 是 帅哥
    False 二两 是 帅哥
    工程师 二两 是 帅哥
    二两 是 美女
"""

# 5.3 高阶函数：以函数作为参数的函数
def add(a, b):
    return a + b

f = add

def new_add(a, b, f):
    return f(a,b) + f(a, b)

ret = new_add(1, 2, f) 
print(ret)
# 5.3.1 内置高阶函数, 简化运算
# map：两个参数，一个是函数，另一个是可迭代对象
def func1(x):
    return x*x

list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ret = map(func1, list1)
print(f'list1={list1},ret={ret},map_list={list(ret)}')
"""
执行结果
    6
    list1=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],ret=<map object at 0x000001F501C5FD30>,map_list=[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
"""

#reduce:两个参数，把结果继续和可迭代对象的下一个元素做累积计算
# reduce函数在python3的内建函数移除了，放入了functools模块
from functools import reduce
def f(a, b):
    return a * 10 + b
ret = reduce(f, [1, 2, 3, 4, 5])
print(ret)
#实现字符串转数字
###way1:
def char2int(src):
    if src < '0' or src > '9':
        # print("请输入数字字符串")
        raise Exception("请输入数字字符串")
    return int(src)

def count(a, b):
    return  a * 10 + b

l1 = []
def str2int(src):
    for i in src:
        ret = char2int(i)
        l1.append(ret)
    ret = reduce(count, l1)
    return ret
ret =  str2int('2589')  
print(f'ret={ret}')
###way2:
import copy

D = {
    '0':0,
    '1':1,
    '2':2,
    '3':3,
    '4':4,
    '5':5,
    '6':6,
    '7':7,
    '8':8,
    '9':9
}

def f(a,b):
    return a*10+b

def char2int(c):
    r = D.get(c, -1)
    if r == -1:
        raise Exception("请输入字符数字")
    return r
# 生成器对象->可迭代对象
r = map(char2int, '1234')
r1 = copy.deepcopy(r)
print(f'r={r},map result:{list(r)}')
print(f'map result2:{list(r)}')#使用一次值被清空

r2 = reduce(f, r1)
print(f'reduce result:{r2}')
"""
执行结果
    12345
    ret=2589
    r=<map object at 0x000001F501C5FBB0>,map result:[1, 2, 3, 4]
    map result2:[]
    reduce result:1234
"""

# 5.3.2 lambda匿名函数:不希望显示定义函数的时候使用
def f(x):
    return x*x

func = lambda x: x * x

ret = map(lambda x: x+1, [1,2,3,4])
print(f'lambda ret = {list(ret)}')

# 5.3.3偏函数：降低调用难度
from functools import partial
int2 = partial(int, base = 2)
print(int2("000"))
print(int2("111"))
print(int2("101"))
"""
执行结果
    lambda ret = [2, 3, 4, 5]
    0
    7
    5
"""

# 5.3.4 递归函数,栈溢出，尾递归解决
def fact(n):
    if n==1:
        return 1
    return n * fact(n -1)
print(fact(6))

# 尾递归
def face(n):
    return face_iter(n, 1)
def face_iter(n, product): #金返回递归函数本身，n-1和n*product在函数调用前就会被计算，不影响函数使用
    if n == 1:
        return product
    return face_iter(n - 1, n*product)
ret = face(5)
print(ret)
"""
    720
    120
"""